import { IEquatable } from "../Utils/IEquatable";


/**
 * 行为片段
 */
export class ActionSegment implements IEquatable<ActionSegment> {

    /**
     * 片段开始点偏移，如果是0就是片段的开始
     */
    public offset: number = 0;


    private _data: number[] = [];
    public get data(): number[] {
        return this._data;
    }
    public set data(value: number[]) {
        this._data = value;
    }

    public get length(): number {
        return this._data.length;
    }
    
    /**
     * 一个空的行为片段
     */
    public static get empty(): ActionSegment {
        return new ActionSegment();
    }

    /**
     * ActionSegment构建函数
     * @param actionArray 实际的数值
     * @param offset 从0开始的偏移量
     * @param length 片段长度
     */
    constructor(actionArray?: number[], offset?: number, length?: number) {
        length = length ?? actionArray?.length ?? 0;

        this._data = new Array<number>(length).fill(0);
        this.offset = offset ?? 0;

        if (actionArray) {
            for (let i = 0; i < length; i++) {
                this.setValue(i, actionArray[i]);
            }
        }
    }

    /**
     * 比较是否相等
     * @param other 其他片段
     * @returns 是否相等
     */
    equals(other: ActionSegment): boolean {
        return this.offset == other.offset && this.length == other.length && this === other;
    }


    /**
     * 获得片段
     * @param index 
     * @returns 
     */
    public getValue(index: number): number {

        if (index < 0 || index > this.length) {
            throw new RangeError(`index out fo bounds, expected a number between 0 and ${this.length}`);
        }

        return this._data[this.offset + index];
    }

    /**
     * 设置片段
     * @param index 
     * @param value 
     */
    public setValue(index: number, value: number) {

        if (index < 0 || index > this.length) {
            throw new RangeError(`index out fo bounds, expected a number between 0 and ${this.length}`);
        }

        this._data[this.offset + index] = value;
    }


    /**
     * 设置所有片段都为0
     */
    public clear(): void {
        this._data.fill(0);
    }

    /**
     * 是否为空片段
     * @returns 
     */
    public isEmpty(): boolean {
        return this.length == 0;
    }

}